package com.ssd.filter;

import com.google.common.base.Strings;
import com.ssd.common.VMSystem;
import com.ssd.config.GatewayConfig;
import com.ssd.utils.Base64Utils;
import com.ssd.utils.JWTUtil;
import com.ssd.utils.JsonUtils;
import com.ssd.view.TokenObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * JWT 过滤器
 */
@Component
@Slf4j
public class JwtTokenFilter implements GlobalFilter, Ordered {

    @Resource
    private GatewayConfig gatewayConfig;

    /**
     * 过滤器处理方法
     * @param exchange ServerWebExchange 对象，包含请求和响应
     * @param chain 过滤链，用于执行后续过滤器
     * @return Mono<Void> 异步处理结果
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求 URL
        String url = exchange.getRequest().getURI().getPath();
        //如果是若依服务直接放行，他自己有自己的拦截处理
        if (url.contains("/admin-service")){
            return chain.filter(exchange);
        }

        // 检查 URL 是否需要验证
        boolean matchUrl = Arrays.stream(gatewayConfig.getUrls())
                .anyMatch(url::contains);
        // 如果不需要验证，直接执行后续过滤器
        if (matchUrl) {
            return chain.filter(exchange);
        }
        // 从请求头中获取 token
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        ServerHttpResponse resp = exchange.getResponse();
        // 如果 token 为空，返回认证错误
        if (Strings.isNullOrEmpty(token)) return authError(resp);

//            // 解码 token 并验证其有效性
//            TokenObject tokenObject = JWTUtil.decode(token);
//            JWTUtil.VerifyResult verifyResult = JWTUtil.verifyJwt(token,  VMSystem.JWT_SECRET);
//            // 如果验证失败，返回认证错误
//            if (!verifyResult.isValidate()) return authError(resp);
//            // 将用户 ID 和登录类型添加到请求头中
//            ServerHttpRequest request = exchange.getRequest().mutate()
//                    .header("loginInfo", Base64Utils.encodeStr(JsonUtils.toJsonStr(tokenObject)))
//                    .build();
//            // 使用新请求执行后续过滤器
            return chain.filter(exchange);
    }

    /**
     * 获取过滤器的顺序，值越小优先级越高
     * @return 顺序值
     */
    @Override
    public int getOrder() {
        return -100;
    }

    /**
     * 认证错误输出
     * @param resp 响应对象
     * @return Mono<Void> 异步处理结果
     */
    private Mono<Void> authError(ServerHttpResponse resp) {
        // 设置响应状态码为 401 未授权
        resp.setStatusCode(HttpStatus.UNAUTHORIZED);
        // 设置响应头的内容类型
        resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        // 设置响应体内容
        String returnStr = "token校验失败";
        DataBuffer buffer = resp.bufferFactory().wrap(returnStr.getBytes(StandardCharsets.UTF_8));
        // 写入响应并返回
        return resp.writeWith(Flux.just(buffer));
    }
}
